import base64
import datetime

from django.core.cache import cache
from django.db import transaction
from django.db.models import Q, Sum, F
from django.forms import model_to_dict
from rest_framework import status, exceptions
from rest_framework.decorators import action
from rest_framework.generics import ListAPIView, RetrieveAPIView
from rest_framework.response import Response
from rest_framework.views import APIView

from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet

from cards.models import Card, RetailerCard, CardDepositRecord, GiftCard, UserGiftCard, CardConsumeRecord, SampleCard, \
    ClientSampleRecord, BalanceBill
from member.api.utils import get_retailer
from member.models import Employee, Retailer
from wine import settings
from wxchat.api.permissions import WeixinPermission
from wxchat.api.utils import get_openid_from_header, get_user_by_openid
from wxchat.models import WxUserInfo
from .serializers import CardSerializer, RetailerCardSerializer, CardDepositRecordSerializer, GiftCardSerializer, \
    UserGiftCardSerializer, CardConsumeRecordSerializer, SampleCardSerializer, ClientSampleRecordSerializer, \
    BalanceBillSerializer


class WxCardViewSet(ModelViewSet):
    """制卡"""
    authentication_classes = ()
    permission_classes = (WeixinPermission,)
    queryset = Card.objects.all()
    serializer_class = CardSerializer

    def get_queryset(self):
        queryset = super().get_queryset()

        retailer_id = self.request.query_params.get("retailer_id", None)

        if retailer_id:
            queryset = queryset.filter(retailer_id=int(retailer_id))

        return queryset


class WxRetailerCardViewSet(ModelViewSet):
    """商家卡"""
    authentication_classes = ()
    permission_classes = (WeixinPermission,)
    queryset = RetailerCard.objects.all()
    serializer_class = RetailerCardSerializer

    def get_queryset(self):
        queryset = super().get_queryset()

        if self.lookup_field in self.kwargs:
            return queryset

        queryset = queryset.filter(ack=1)

        retailer_id = self.request.query_params.get("retailer_id", None)
        card_retailer_id = self.request.query_params.get("card_retailer_id", None)

        if retailer_id:
            queryset = queryset.filter(retailer_id=int(retailer_id))

        if card_retailer_id:
            queryset = queryset.filter(card__retailer_id=int(card_retailer_id))

        return queryset


class WxUserGiftCardViewSet(ModelViewSet):
    """客户会员卡"""
    authentication_classes = ()
    permission_classes = (WeixinPermission,)
    queryset = UserGiftCard.objects.all()
    serializer_class = UserGiftCardSerializer

    def get_queryset(self):
        queryset = super().get_queryset()
        retailer_id = self.request.query_params.get("retailer_id", None)
        openid = self.request.query_params.get("openid", None)
        flag = self.request.query_params.get("flag", None)  # flag = 1 为 正常卡 0为待激活卡

        if retailer_id:
            queryset = queryset.filter(r_card__retailer_id=int(retailer_id))

        if openid:
            queryset = queryset.filter(openid=openid)

        if flag == "1":
            queryset = queryset.filter(r_count__gt=0)
        elif flag == "0":
            queryset = queryset.filter(r_unused_count__gt=0)

        return queryset


class WxCardConsumeAPIView(APIView):
    """优惠卡消费"""
    authentication_classes = ()
    permission_classes = (WeixinPermission,)

    def post(self, request):
        msg = {
            "status_code": "",
            "message": "",
            "data": {},
        }
        key = request.data.get("key", None)
        retailer_openid = get_openid_from_header(request)  # 商家OPENID

        if key:
            url = cache.get(key)
            if url is None:
                msg["status_code"] = status.HTTP_401_UNAUTHORIZED
                msg["message"] = "二维码失效,请重新扫码"
                return Response(msg)
            else:
                client_openid = request.data.get("pid", None)
                client_openid = base64.b64decode(client_openid).decode()
                client_user = get_user_by_openid(client_openid)

                card_id = request.data.get("card_id", None)
                card_id = int(card_id)
                count = request.data.get("count", None)

                try:
                    count = int(count)
                    if count < 0:
                        raise ValueError
                except ValueError:
                    msg["status_code"] = status.HTTP_401_UNAUTHORIZED
                    msg["message"] = "数据异常！！"
                    return Response(msg)

                # 判断积分是否充足
                user_card = UserGiftCard.objects.filter(id=card_id).first()
                if not user_card:
                    msg["status_code"] = status.HTTP_401_UNAUTHORIZED
                    msg["message"] = "此卡不存在！！"
                    return Response(msg)

                card_count = user_card.r_count or 0
                if card_count < count:
                    msg["status_code"] = status.HTTP_401_UNAUTHORIZED
                    msg["message"] = "数量不足！！"
                    return Response(msg)

                ok = CardConsumeRecord.objects.filter(consume_key=key).exists()
                if ok:
                    msg["status_code"] = status.HTTP_401_UNAUTHORIZED
                    msg["message"] = "已经消费完毕,无须再次操作"
                    return Response(msg)

                employee_user = Employee.objects.filter(openid=retailer_openid).first()

                if employee_user:
                    r_name = employee_user.name
                    retailer_id = employee_user.retailer_id
                else:
                    retailer = Retailer.objects.get(openid=retailer_openid)
                    if retailer:
                        r_name = retailer.person
                        retailer_id = retailer.id
                    else:
                        msg["status_code"] = status.HTTP_401_UNAUTHORIZED
                        msg["message"] = "此商家不合法!"
                        return Response(msg)

                with transaction.atomic():
                    save_id = transaction.savepoint()
                    try:
                        # 客户扣除优惠卡
                        user_card = UserGiftCard.objects.get(id=card_id)
                        user_card.r_count -= count
                        user_card.save(update_fields=["r_count"])

                        # 创建客户优惠卡消费记录
                        data = {
                            "openid": client_openid,
                            "name": client_user.name or client_user.nickname,
                            "retailer_id": retailer_id,
                            "r_openid": retailer_openid,
                            "r_name": r_name,
                            "r_card_id": card_id,
                            "r_count": count,
                            "consume_key": key
                        }
                        obj = CardConsumeRecord.objects.create(**data)
                        msg["status_code"] = status.HTTP_200_OK
                        msg["message"] = "客户优惠卡消费成功"
                        rec = CardConsumeRecord.objects.filter(id=obj.id).first()

                        serializer = CardConsumeRecordSerializer(rec)
                        msg["data"] = serializer.data
                        # 发送模板消息
                        # if obj:
                        #     send_consumption_message_to_client(obj)

                    except Exception as ex:
                        print(ex)
                        transaction.savepoint_rollback(save_id)
                        msg["status_code"] = status.HTTP_401_UNAUTHORIZED
                        msg["message"] = "客户优惠卡消费失败, 请联系管理员"
                        return Response(msg)

                    transaction.savepoint_commit(save_id)
                    cache.delete(key)
        else:
            msg["status_code"] = status.HTTP_401_UNAUTHORIZED
            msg["message"] = "参数错误"

        return Response(msg)


class WxGiftCardViewSet(ReadOnlyModelViewSet):
    """赠送卡"""
    authentication_classes = ()
    permission_classes = (WeixinPermission,)
    queryset = GiftCard.objects.all()
    serializer_class = GiftCardSerializer

    def get_queryset(self):
        queryset = super().get_queryset()
        name = self.request.query_params.get("name", None)

        openid = self.request.query_params.get("openid", None)
        r_openid = self.request.query_params.get("r_openid", None)

        retailer_id = self.request.query_params.get("retailer_id", None)
        begin_date = self.request.query_params.get("begin_date", None)
        end_date = self.request.query_params.get("end_date", None)

        if openid:
            queryset = queryset.filter(customer_openid=openid)

        if retailer_id:
            if r_openid:
                retailer = get_retailer(r_openid)
                if retailer:
                    queryset = queryset.filter(retailer_id=int(retailer_id))
                else:
                    queryset = queryset.filter(retailer_id=int(retailer_id), openid=r_openid)
            else:
                return GiftCard.objects.none()

        if name:
            queryset = queryset.filter(Q(name__contains=name) | Q(customer_name__contains=name))

        if begin_date and end_date:
            queryset = queryset.filter(update_time__date__range=(begin_date, end_date))

        return queryset


# class CardDepositRecordViewSet(ModelViewSet):
#     """商家购卡表"""
#     # authentication_classes = ()
#     permission_classes = ()
#     queryset = CardDepositRecord.objects.all()
#     serializer_class = CardDepositRecordSerializer
#
#     def get_queryset(self):
#         queryset = super().get_queryset()
#         name = self.request.query_params.get("name", None)
#         retailer_id = self.request.query_params.get("retailer_id", None)
#         out_trade_no = self.request.query_params.get("out_trade_no", None)
#         telephone = self.request.query_params.get("telephone", None)
#         search_date = self.request.query_params.getlist("search_date[]", None)
#
#         if retailer_id:
#             queryset = queryset.filter(retailer_id=int(retailer_id))
#
#         if name:
#             queryset = queryset.filter(Q(name__contains=name) | Q(openid__contains=name))
#
#         if out_trade_no:
#             queryset = queryset.filter(out_trade_no__contains=out_trade_no)
#
#         if telephone:
#             queryset = queryset.filter(telephone=telephone)
#
#         if search_date and len(search_date) == 2:
#             queryset = queryset.filter(pay_time__date__range=(search_date[0], search_date[1]))
#
#         return queryset
#
#     @action(methods=['delete'], detail=False)
#     def batch_delete(self, request, *args, **kwargs):
#         select_ids = request.data.get("select_ids", None)
#         if not select_ids:
#             msg = {"status_code": status.HTTP_404_NOT_FOUND, "message": "删除失败!"}
#             return Response(data=msg, status=status.HTTP_404_NOT_FOUND)
#
#         self.serializer_class.Meta.model.objects.filter(id__in=select_ids).delete()
#         msg = {"status_code": status.HTTP_204_NO_CONTENT, "message": "删除成功!"}
#         return Response(data=msg, status=status.HTTP_204_NO_CONTENT)
#
#
#
class WxCardConsumeRecordViewSet(ReadOnlyModelViewSet):
    """客户会员卡消费记录"""
    authentication_classes = ()
    permission_classes = (WeixinPermission,)
    queryset = CardConsumeRecord.objects.all()
    serializer_class = CardConsumeRecordSerializer

    def get_queryset(self):
        queryset = super().get_queryset()
        name = self.request.query_params.get("name", None)
        openid = self.request.query_params.get("openid", None)
        r_openid = self.request.query_params.get("r_openid", None)
        retailer_id = self.request.query_params.get("retailer_id", None)
        r_card = self.request.query_params.get("r_card", None)
        begin_date = self.request.query_params.get("begin_date", None)
        end_date = self.request.query_params.get("end_date", None)

        if openid:
            queryset = queryset.filter(openid=openid)

        if retailer_id:

            if r_openid:
                retailer = get_retailer(r_openid)
                if retailer:
                    queryset = queryset.filter(retailer_id=int(retailer_id))
                else:
                    queryset = queryset.filter(retailer_id=int(retailer_id), r_openid=r_openid)
            else:
                return CardConsumeRecord.objects.none()

        if name:
            queryset = queryset.filter(Q(name__contains=name) | Q(r_name__contains=name))

        if r_card:
            queryset = queryset.filter(r_card_id=int(r_card))

        if begin_date and end_date:
            queryset = queryset.filter(update_time__date__range=(begin_date, end_date))

        return queryset


class WxDiscountCardVerifyAPIView(APIView):
    """优惠卡审核授权"""
    authentication_classes = ()
    permission_classes = (WeixinPermission,)

    def post(self, request, *args, **kwargs):
        msg = {
            "status_code": "",
            "message": "",
            "data": {},
        }
        key = request.data.get("key", None)
        openid = get_openid_from_header(request)
        retailer = get_retailer(openid)

        if key:
            url = cache.get(key)
            if url is None:
                msg["status_code"] = status.HTTP_401_UNAUTHORIZED
                msg["message"] = "二维码失效,请重新扫码"
                return Response(msg)
            else:
                card_id = request.data.get("card_id", None)

                c_openid = request.data.get("pid", None)
                c_openid = base64.b64decode(c_openid)
                c_openid = c_openid.decode()

                comment = request.data.get("comment", None)
                comment = base64.b64decode(comment)
                comment = comment.decode()

                discount = request.data.get("discount", None)
                discount = int(discount)

                print(card_id, c_openid, comment, discount, openid, key)
                ok = RetailerCard.objects.filter(key=key, ack=1).exists()
                if ok:
                    msg["status_code"] = status.HTTP_401_UNAUTHORIZED
                    msg["message"] = "此授权码已经使用,无法再次使用"
                    return Response(msg)

                card = RetailerCard.objects.filter(card_id=int(card_id), retailer=retailer, ack=1).first()
                if card:
                    msg["data"] = model_to_dict(card)
                    msg["status_code"] = status.HTTP_401_UNAUTHORIZED
                    msg["message"] = "此卡已经授权，无法再次授权"
                    return Response(msg)

                r_user = get_user_by_openid(openid)
                c_user = get_user_by_openid(c_openid)
                if c_user and r_user:
                    data = {
                        "card_id": int(card_id),
                        "retailer": retailer,
                        "r_openid": openid,
                        "r_name": r_user.name or r_user.nickname,
                        "c_openid": c_user.openid,
                        "c_name": c_user.name or c_user.nickname,
                        "comment": comment,
                        "discount": discount,
                        "ack": 1,
                        "key": key
                    }
                    obj = RetailerCard.objects.create(**data)

                    serializer = RetailerCardSerializer(instance=obj)
                    card = serializer.data
                    card.pop("key")
                    card.pop("r_openid")
                    card.pop("c_openid")
                    card.pop("retailer")
                    msg["status_code"] = status.HTTP_200_OK
                    msg["message"] = "授权成功"
                    msg["data"] = card
                    cache.delete(key)
                else:
                    msg["status_code"] = status.HTTP_401_UNAUTHORIZED
                    msg["message"] = "用户不存在, 请确认是否关注公众号"
                    return Response(msg)
        else:
            msg["status_code"] = status.HTTP_401_UNAUTHORIZED
            msg["message"] = "参数错误"

        return Response(msg)


class WxCardGiftAPIView(APIView):
    """优惠卡赠送"""
    authentication_classes = ()
    permission_classes = (WeixinPermission,)

    def post(self, request, *args, **kwargs):
        msg = {
            "status_code": "",
            "message": "",
            "data": {},
        }
        key = request.data.get("key", None)
        if key:
            url = cache.get(key)
            openid = get_openid_from_header(request)  # 客户OPENID
            user = get_user_by_openid(openid)
            if url is None:
                msg["status_code"] = status.HTTP_401_UNAUTHORIZED
                msg["message"] = "二维码失效,请重新扫码"
                return Response(msg)
            else:
                card_id = request.data.get("card_id", None)

                retailer_openid = request.data.get("pid", None)
                retailer_openid = base64.b64decode(retailer_openid)
                retailer_openid = retailer_openid.decode()

                retailer_id = request.data.get("retailer_id", None)
                retailer_id = int(retailer_id)

                count = request.data.get("count", None)
                try:
                    count = int(count)
                    if count < 0:
                        raise ValueError
                except ValueError:
                    msg["status_code"] = status.HTTP_401_UNAUTHORIZED
                    msg["message"] = "数据异常！！"
                    return Response(msg)

                ok = GiftCard.objects.filter(order_key=key).exists()
                if ok:
                    msg["status_code"] = status.HTTP_401_UNAUTHORIZED
                    msg["message"] = "积分已经赠送完毕,无须再次操作"
                    return Response(msg)

                with transaction.atomic():
                    save_id = transaction.savepoint()
                    try:
                        # 商家减积分
                        card = RetailerCard.objects.get(id=int(card_id))

                        if card.count is None:
                            card.count = 0

                        if card.count >= count:
                            unused_count = 0
                            used_count = count
                        else:
                            if card.count > 0:
                                unused_count = count - card.count
                                used_count = card.count
                            else:
                                used_count = 0
                                unused_count = count

                        card.count -= count
                        card.save(update_fields=["count"])

                        employee_user = Employee.objects.filter(openid=retailer_openid).first()
                        name = ""
                        branch = ""
                        if employee_user:
                            name = employee_user.name
                            branch = employee_user.branch
                        else:
                            retailer_user = Retailer.objects.get(openid=retailer_openid)
                            if retailer_user:
                                name = retailer_user.person
                            else:
                                wx_user = WxUserInfo.objects.get(openid=retailer_openid)
                                name = wx_user.name or wx_user.nickname

                        # 客户增加优惠卡
                        user_card = UserGiftCard.objects.filter(openid=openid, r_card_id=int(card_id)).first()
                        if user_card:
                            user_card.r_count += used_count
                            user_card.r_unused_count += unused_count

                            user_card.save(update_fields=["r_count", "r_unused_count"])
                            msg["status_code"] = status.HTTP_200_OK
                            msg["message"] = "成功领取优惠卡"
                        else:
                            data = {
                                "openid": openid,
                                "name": user.name or user.nickname,
                                "retailer_id": card.card.retailer_id,
                                "r_card_id": int(card_id),
                                "r_count": used_count or 0,
                                "r_unused_count": unused_count or 0,
                            }
                            obj = UserGiftCard.objects.create(**data)
                            msg["status_code"] = status.HTTP_200_OK
                            msg["message"] = "成功领取优惠卡"
                        # 赠送记录
                        data = {
                            "retailer_id": int(retailer_id),
                            "openid": retailer_openid,
                            "name": name,
                            "branch": branch,
                            "customer_openid": openid,
                            "customer_name": user.name or user.nickname,
                            "r_card_id": int(card_id),
                            "r_count": used_count or 0,
                            "r_unused_count": unused_count or 0,
                            "order_key": key,
                            "status": 1  # 赠送
                        }
                        obj = GiftCard.objects.create(**data)
                        card_info = GiftCard.objects.filter(id=obj.id).first()
                        if card_info:
                            serializer = GiftCardSerializer(card_info)
                            msg["data"] = serializer.data
                        # 发送模板消息
                        # if obj:
                        #     # 商家
                        #     send_message_to_retailer(obj)
                        #     # 客户
                        #     send_message_to_client(obj)
                    except Exception as ex:
                        print(ex)
                        transaction.savepoint_rollback(save_id)
                        msg["status_code"] = status.HTTP_401_UNAUTHORIZED
                        msg["message"] = "赠送优惠卡失败！"
                        return Response(msg)

                    transaction.savepoint_commit(save_id)
                    cache.delete(key)
        else:
            msg["status_code"] = status.HTTP_401_UNAUTHORIZED
            msg["message"] = "参数错误"

        return Response(msg)


class BalanceAccountsStats(APIView):
    """
    各个商家优惠卡结算账单
    """
    authentication_classes = ()
    permission_classes = ()

    def get(self, request, *args, **kwargs):
        retailer_id = self.request.query_params.get("retailer_id", None)
        ym = self.request.query_params.get("ym", None)

        queryset = GiftCard.objects.all()

        if retailer_id:
            queryset = queryset.filter(retailer_id=int(retailer_id))

        if ym:
            d_ym = datetime.datetime.strptime(ym, "%Y-%m")
            queryset = queryset.filter(update_time__year=d_ym.year, update_time__month=d_ym.month)

        total_results = queryset.values(r_id=F('r_card__card__retailer'), r_name=F('r_card__card__retailer__name'))\
            .order_by('r_id')\
            .annotate(
                r_counts=Sum("r_count"),
                total_money=Sum(F("r_count") * F("r_card__card__amount") * F("r_card__discount") * 0.01),
                r_unused_counts=Sum("r_unused_count"),
                unused_total_money=Sum(F("r_unused_count") * F("r_card__card__amount") * F("r_card__discount") * 0.01)
            )

        total_results = list(total_results)

        results = queryset.values(r_id=F('r_card__card__retailer'), r_name=F('r_card__card__retailer__name'),
                                  card_id=F('r_card'), r_card_name=F('r_card__card__name'), r_card_amount=F('r_card__card__amount')).order_by('r_id', 'card_id')\
            .annotate(
                r_counts=Sum("r_count"),
                total_money=Sum(F("r_count") * F("r_card__card__amount") * F("r_card__discount") * 0.01),
                r_unused_counts=Sum("r_unused_count"),
                unused_total_money=Sum(F("r_unused_count") * F("r_card__card__amount") * F("r_card__discount") * 0.01)
            )

        results = list(results)

        for result in total_results:
            result["children"] = list()
            for r in results:
                if r["r_id"] == result["r_id"]:
                    result["children"].append(r)

        return Response(total_results)


class MyBalanceAccountsStats(APIView):
    """
    商家自己优惠卡使用结算账单
    """
    authentication_classes = ()
    permission_classes = ()

    def get(self, request, *args, **kwargs):
        retailer_id = self.request.query_params.get("retailer_id", None)
        ym = self.request.query_params.get("ym", None)

        queryset = GiftCard.objects.all()

        if retailer_id:
            queryset = queryset.filter(r_card__card__retailer_id=int(retailer_id))

        if ym:
            d_ym = datetime.datetime.strptime(ym, "%Y-%m")
            queryset = queryset.filter(update_time__year=d_ym.year, update_time__month=d_ym.month)

        total_results = queryset.values(r_id=F('retailer_id'), r_name=F('retailer__name')).order_by('r_id') \
            .annotate(
            r_counts=Sum("r_count"),
            total_money=Sum(F("r_count") * F("r_card__card__amount") * F("r_card__discount") * 0.01),
            r_unused_counts=Sum("r_unused_count"),
            unused_total_money=Sum(F("r_unused_count") * F("r_card__card__amount") * F("r_card__discount") * 0.01)
        )

        total_results = list(total_results)

        results = queryset.values(r_id=F('retailer_id'), r_name=F('retailer__name'),
                                  card_id=F('r_card'), r_card_name=F('r_card__card__name'), r_card_amount=F('r_card__card__amount')).order_by('r_id', 'card_id')\
            .annotate(
                r_counts=Sum("r_count"),
                total_money=Sum(F("r_count") * F("r_card__card__amount") * F("r_card__discount") * 0.01),
                r_unused_counts=Sum("r_unused_count"),
                unused_total_money=Sum(F("r_unused_count") * F("r_card__card__amount") * F("r_card__discount") * 0.01)
            )
        # print(results)
        results = list(results)

        for result in total_results:
            result["children"] = list()
            for r in results:
                if r["r_id"] == result["r_id"]:
                    result["children"].append(r)

        return Response(total_results)


class WxSampleCardViewSet(ModelViewSet):
    """客户品鉴卡"""
    authentication_classes = ()
    permission_classes = (WeixinPermission,)
    queryset = SampleCard.objects.all()
    serializer_class = SampleCardSerializer
    http_method_names = ["get", "post"]

    def get_queryset(self):
        queryset = super().get_queryset()
        openid = get_openid_from_header(self.request)

        if openid:
            queryset = queryset.filter(openid=openid)

        return queryset


class SampleCardRetriveAPIView(RetrieveAPIView):
    """品鉴卡"""
    authentication_classes = ()
    permission_classes = (WeixinPermission,)
    queryset = SampleCard.objects.all()
    serializer_class = SampleCardSerializer
    lookup_field = "key"


class WxSampleCardAPIView(APIView):
    """品鉴卡"""
    authentication_classes = ()
    permission_classes = (WeixinPermission,)

    def get(self, request, *args, **kwargs):
        openid = get_openid_from_header(request)
        card_id = request.query_params.get("card_id", None)
        if not openid or not card_id:
            msg = {
                'status_code': status.HTTP_400_BAD_REQUEST,
                'message': '参数错误！'
            }
            return Response(msg)

        user = get_user_by_openid(openid)
        if user and user.staff in [1, 2]:
            msg = {
                'status_code': status.HTTP_400_BAD_REQUEST,
                'message': '管理人员'
            }
            return Response(msg)

        sample = SampleCard.objects.filter(card_id=int(card_id), openid=openid).first()
        if not sample:
            msg = {
                'status_code': status.HTTP_400_BAD_REQUEST,
                'message': '未领取品鉴卡'
            }
            return Response(msg)

        serializer = SampleCardSerializer(sample)
        msg = {
            'status_code': status.HTTP_200_OK,
            'message': '',
            'data': serializer.data
        }
        return Response(msg)


class WxClientSampleRecordViewSet(ModelViewSet):
    """客户品鉴卡核销记录"""
    authentication_classes = ()
    permission_classes = (WeixinPermission,)
    queryset = ClientSampleRecord.objects.all()
    serializer_class = ClientSampleRecordSerializer
    http_method_names = ["get"]

    def get_queryset(self):
        queryset = super().get_queryset()
        openid = get_openid_from_header(self.request)
        flag = self.request.query_params.get("flag", None)
        retailer_id = self.request.query_params.get("retailer_id", None)
        begin_date = self.request.query_params.get("begin_date", None)
        end_date = self.request.query_params.get("end_date", None)

        if not flag and openid:
            queryset = queryset.filter(openid=openid)
            return queryset

        if flag and flag == "1":   # 商家
            retailer = get_retailer(openid)
            if retailer:
                queryset = queryset.filter(retailer=retailer)
                if begin_date and end_date:
                    queryset = queryset.filter(add_time__date__range=[begin_date, end_date])
                return queryset
        elif flag and flag == "2":
            queryset = queryset.filter(retailer_id=int(retailer_id), balance_flag=0)
            return queryset

        return self.serializer_class.Meta.model.objects.none()


class WxClientSampleConfirmAPIView(APIView):
    """品鉴卡核销"""
    authentication_classes = ()
    permission_classes = (WeixinPermission,)

    def post(self, request, *args, **kwargs):
        retailer_openid = get_openid_from_header(request)
        key = request.data.get("key", None)
        pid = request.data.get("pid", None)
        openid = base64.b64decode(pid).decode()
        if not retailer_openid or not key or not openid:
            msg = {
                'status_code': status.HTTP_400_BAD_REQUEST,
                'message': '参数错误！'
            }
            raise exceptions.ValidationError(msg)

        if not SampleCard.objects.filter(key=key, status=0).exists():
            msg = {
                'status_code': status.HTTP_400_BAD_REQUEST,
                'message': '抱歉，此卡已经领取过了, <br><B style="color:red;font-size:18px;">核销失败!</B>',
                'toast': '抱歉，此卡已经领取过了, 核销失败!'
            }
            raise exceptions.ValidationError(msg)

        sample_card = SampleCard.objects.filter(key=key).first()
        if ClientSampleRecord.objects.filter(openid=openid, card_id=sample_card.card_id).exists():
            msg = {
                'status_code': status.HTTP_400_BAD_REQUEST,
                'message': '抱歉，此卡已经领取过了, <br><B style="color:red;font-size:18px;">核销失败!</B>',
                'toast': '抱歉，此卡已经领取过了, 核销失败!'
            }
            raise exceptions.ValidationError(msg)

        retailer = get_retailer(retailer_openid)

        if not retailer:
            msg = {
                'status_code': status.HTTP_400_BAD_REQUEST,
                'message': '您无权核销!'
            }
            raise exceptions.ValidationError(msg)

        sc_record = None

        with transaction.atomic():
            # 创建事务保存点
            save_id = transaction.savepoint()
            try:
                # 更新
                SampleCard.objects.filter(key=key).update(status=1)
                # 插入记录
                client = get_user_by_openid(openid)
                retailer_user = get_user_by_openid(retailer_openid)

                if not client or not retailer_user:
                    msg = {
                        'status_code': status.HTTP_400_BAD_REQUEST,
                        'message': '数据非法！'
                    }
                    raise exceptions.ValidationError(msg)

                record = {
                    "openid": openid,
                    "name": client.name or client.nickname,
                    "r_openid": retailer_openid,
                    "r_name": retailer_user.name or retailer_user.nickname,
                    "card": sample_card.card,
                    "retailer": retailer,
                }
                sc_record = ClientSampleRecord.objects.create(**record)

            except Exception as e:
                print("exception: ", e)
                transaction.savepoint_rollback(save_id)
                msg = {
                    'status_code': status.HTTP_400_BAD_REQUEST,
                    'message': '核销品鉴卡失败'
                }
                raise exceptions.ValidationError(msg)

            transaction.savepoint_commit(save_id)

        serializer = ClientSampleRecordSerializer(sc_record)

        msg = {
            'status_code': status.HTTP_200_OK,
            'message': '核销品鉴卡成功',
            "data": serializer.data
        }
        return Response(msg)


class BalanceBillAPIView(APIView):
    """结算"""
    authentication_classes = ()
    permission_classes = (WeixinPermission,)

    def post(self, request, *args, **kwargs):
        openid = get_openid_from_header(request)
        balance_date = request.data.get("balance_date", None)
        retailer_id = request.data.get("retailer_id", None)
        retailer_id = int(retailer_id)
        if not any([openid, balance_date, retailer_id]):
            msg = {
                'status_code': status.HTTP_200_OK,
                'message': '参数错误!',

            }
            return Response(msg)

        counts = ClientSampleRecord.objects.filter(retailer_id=retailer_id, add_time__date__lte=balance_date, balance_flag=0).count()
        if counts == 0:
            msg = {
                'status_code': status.HTTP_200_OK,
                'message': '无结算数据!',

            }
            return Response(msg)

        with transaction.atomic():
            # 创建事务保存点
            save_id = transaction.savepoint()
            try:
                # 更新
                ClientSampleRecord.objects.filter(retailer_id=retailer_id, add_time__date__lte=balance_date, balance_flag=0)\
                    .update(balance_date=balance_date, balance_flag=1, balance_time=datetime.datetime.now())
                # 插入记录
                user = get_user_by_openid(openid)
                if not user:
                    msg = {
                        'status_code': status.HTTP_400_BAD_REQUEST,
                        'message': '数据非法！'
                    }
                    raise exceptions.ValidationError(msg)

                bill = {
                    "openid": openid,
                    "name": user.name or user.nickname,
                    "retailer_id": retailer_id,
                    "counts": counts,
                    "bill_date": balance_date,
                }
                BalanceBill.objects.create(**bill)

            except Exception as e:
                print("exception: ", e)
                transaction.savepoint_rollback(save_id)
                msg = {
                    'status_code': status.HTTP_400_BAD_REQUEST,
                    'message': '结算失败'
                }
                raise exceptions.ValidationError(msg)

            transaction.savepoint_commit(save_id)

        msg = {
            'status_code': status.HTTP_200_OK,
            'message': '结算成功',
        }
        return Response(msg)


class BalanceBillListAPIView(ListAPIView):
    """结算单列表"""
    authentication_classes = ()
    permission_classes = (WeixinPermission,)
    queryset = BalanceBill.objects.all()
    serializer_class = BalanceBillSerializer

    def get_queryset(self):
        queryset = super().get_queryset()

        openid = get_openid_from_header(self.request)

        retailer_id = self.request.query_params.get("retailer_id", None)
        flag = self.request.query_params.get("flag", None)
        begin_date = self.request.query_params.get("begin_date", None)
        end_date = self.request.query_params.get("end_date", None)

        retailer = get_retailer(openid)
        if retailer and not flag:
            queryset = queryset.filter(retailer_id=retailer.id)

            if begin_date and end_date:
                queryset = queryset.filter(bill_date__range=[begin_date, end_date])

            return queryset

        user = get_user_by_openid(openid)
        if int(flag) == 1 and user and user.staff in [1, 2]:
            if retailer_id:
                queryset = queryset.filter(retailer_id=int(retailer_id))

            if begin_date and end_date:
                queryset = queryset.filter(bill_date__range=[begin_date, end_date])

            return queryset

        return BalanceBill.objects.none()


class BalanceBillStatsAPIView(APIView):
    """结算单列表"""
    authentication_classes = ()
    permission_classes = (WeixinPermission,)

    def get(self, request, *args, **kwargs):
        openid = get_openid_from_header(request)

        flag = self.request.query_params.get("flag", None)

        retailer_id = request.query_params.get("retailer_id", None)
        begin_date = request.query_params.get("begin_date", None)
        end_date = request.query_params.get("end_date", None)

        queryset = BalanceBill.objects.all()

        retailer = get_retailer(openid)
        if retailer and not flag:
            queryset = queryset.filter(retailer_id=retailer.id)

            if begin_date and end_date:
                queryset = queryset.filter(bill_date__range=[begin_date, end_date])

            results = queryset.aggregate(counts=Sum("counts"))

            return Response(results)

        user = get_user_by_openid(openid)
        if int(flag) == 1 and user and user.staff in [1, 2]:
            if retailer_id:
                queryset = queryset.filter(retailer_id=int(retailer_id))

            if begin_date and end_date:
                queryset = queryset.filter(bill_date__range=[begin_date, end_date])

            results = queryset.aggregate(counts=Sum("counts"))
            return Response(results)

        results = {
            "counts": 0
        }
        return Response(results)
